package com.ehome.poct.core.service;

import com.ehome.poct.base.api.vo.device.TestDeviceVO;
import com.ehome.poct.core.api.common.Age;
import com.ehome.poct.core.api.dto.check.*;
import com.ehome.poct.core.api.dto.common.Sex;
import com.ehome.poct.core.api.dto.common.DeviceCheckStatusEnum;
import com.ehome.poct.core.api.dto.common.InitiateTypeEnum;
import com.ehome.poct.core.api.dto.patient.AddPatientDTO;
import com.ehome.poct.core.api.dto.patient.Patient;
import com.ehome.poct.core.api.dto.patient.PatientDetail;
import com.ehome.poct.core.api.virtual.OnlineCheckService;
import com.ehome.poct.core.api.vo.online.TodoOrderVO;
import com.ehome.poct.core.api.vo.patient.PatientDetailVO;
import com.ehome.poct.core.repository.CheckPublisher;
import com.ehome.poct.core.repository.OnlineCheckRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

/**
 * @author gyl
 * @since 2022/3/5 14:01
 **/
@Service
public class OnlineCheckServiceImpl implements OnlineCheckService {
    @Autowired
    private OnlineCheckRepository onlineCheckRepository;
    @Autowired
    private CheckPublisher publisher;

    @Override
    public TodoOrderVO startOnline(OnlineCheckDTO checkDTO) {
        // 2. 添加患者联机检测记录
        var record = toCheckOnlineRecord(checkDTO.getPatient());
        record = onlineCheckRepository.saveUniRecord(record);

        // 3. 发送联机事件
        final var event = toOnlineStartedEvent(checkDTO.getPatient(), record,checkDTO.getDevice());
        publisher.publishOnlineEvent(event);
        return toTodoOrderVO(event);
    }

    @Override
    public List<TodoOrderVO> getTodoList(Long clinicId) {
        return onlineCheckRepository.getTodoList(clinicId);
    }

    @Override
    public Boolean delTodoOrder(Long recordId) {
        return onlineCheckRepository.deleteUniRecord(recordId)>0;
    }

    @Override
    public Boolean todoIsExist(Long recordId) {
        return null != onlineCheckRepository.findById(recordId);
    }

    @Override
    public Boolean editUniRecord(Long recordId) {
        return onlineCheckRepository.updateUniRecordStatus(recordId, DeviceCheckStatusEnum.FINISH, null)>0;
    }


    private CheckOnlineRecord toCheckOnlineRecord(PatientDetailVO patient) {
        return new CheckOnlineRecord(patient.getClinicId(), patient.getPatientId(), patient.getUserName(), InitiateTypeEnum.FROM_BLOOD,
                new DeviceCheckProcess(DeviceCheckStatusEnum.IN_PROGRESS), new DeviceCheckProcess(DeviceCheckStatusEnum.WAIT), null);
    }

    private OnlineStartedEvent toOnlineStartedEvent(PatientDetailVO patient, CheckOnlineRecord record, TestDeviceVO device) {
        return new OnlineStartedEvent(record.getId(), record.getClinicId(), record.getPatientId(),
                record.getBloodProcess(), record.getPoctProcess(), record.getCreateTime(),new PatientDetail( patient),device.getVersion());
    }

    private TodoOrderVO toTodoOrderVO(OnlineStartedEvent event) {
        final var detail = event.getDetail();
        final var patient = new PatientDetailVO(event.getPatientId(), event.getClinicId(), detail.getName(), detail.getPhone(),
                detail.getAge().getYear(), detail.getAge().getMonth(), detail.getSex().getValue());
        return new TodoOrderVO().setRecordId(event.getRecordId()).setCreateTime(event.getCreateTime()).setPatient(patient);
    }

    private Patient toPatient(AddPatientDTO cmd) {
        return new Patient(cmd.getClinicId(),
                new PatientDetail(cmd.getUserName(), Sex.findByValue(cmd.getUserSex()), cmd.getMobilePhone(), new Age(cmd.getUserAge(), cmd.getUserMonth())));
    }
}
